package cn.edu.scau.cmi.hombio.service;

import cn.edu.scau.cmi.hombio.dao.MedicineDAO;
import cn.edu.scau.cmi.hombio.dao.PreventionTypeDAO;
import cn.edu.scau.cmi.hombio.dao.TaskPreventionDAO;
import cn.edu.scau.cmi.hombio.dao.UnitDAO;

import cn.edu.scau.cmi.hombio.domain.Medicine;
import cn.edu.scau.cmi.hombio.domain.PreventionType;
import cn.edu.scau.cmi.hombio.domain.TaskPrevention;
import cn.edu.scau.cmi.hombio.domain.Unit;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for PreventionType entities
 * 
 */

@Service("PreventionTypeService")

@Transactional
public class PreventionTypeServiceImpl implements PreventionTypeService {

	/**
	 * DAO injected by Spring that manages Medicine entities
	 * 
	 */
	@Autowired
	private MedicineDAO medicineDAO;

	/**
	 * DAO injected by Spring that manages PreventionType entities
	 * 
	 */
	@Autowired
	private PreventionTypeDAO preventionTypeDAO;

	/**
	 * DAO injected by Spring that manages TaskPrevention entities
	 * 
	 */
	@Autowired
	private TaskPreventionDAO taskPreventionDAO;

	/**
	 * DAO injected by Spring that manages Unit entities
	 * 
	 */
	@Autowired
	private UnitDAO unitDAO;

	/**
	 * Instantiates a new PreventionTypeServiceImpl.
	 *
	 */
	public PreventionTypeServiceImpl() {
	}

	/**
	 * Delete an existing PreventionType entity
	 * 
	 */
	@Transactional
	public void deletePreventionType(PreventionType preventiontype) {
		preventionTypeDAO.remove(preventiontype);
		preventionTypeDAO.flush();
	}

	/**
	 * Return a count of all PreventionType entity
	 * 
	 */
	@Transactional
	public Integer countPreventionTypes() {
		return ((Long) preventionTypeDAO.createQuerySingleResult("select count(o) from PreventionType o").getSingleResult()).intValue();
	}

	/**
	 * Save an existing Medicine entity
	 * 
	 */
	@Transactional
	public PreventionType savePreventionTypeMedicineByMedicineId(Integer id, Medicine related_medicinebymedicineid) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(id, -1, -1);
		Medicine existingmedicineByMedicineId = medicineDAO.findMedicineByPrimaryKey(related_medicinebymedicineid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingmedicineByMedicineId != null) {
			existingmedicineByMedicineId.setId(related_medicinebymedicineid.getId());
			existingmedicineByMedicineId.setName(related_medicinebymedicineid.getName());
			existingmedicineByMedicineId.setNumber(related_medicinebymedicineid.getNumber());
			existingmedicineByMedicineId.setCompany(related_medicinebymedicineid.getCompany());
			existingmedicineByMedicineId.setQuantityPerCase(related_medicinebymedicineid.getQuantityPerCase());
			existingmedicineByMedicineId.setQuantityPerBox(related_medicinebymedicineid.getQuantityPerBox());
			existingmedicineByMedicineId.setPhone(related_medicinebymedicineid.getPhone());
			existingmedicineByMedicineId.setMemo(related_medicinebymedicineid.getMemo());
			related_medicinebymedicineid = existingmedicineByMedicineId;
		}

		preventiontype.setMedicineByMedicineId(related_medicinebymedicineid);
		related_medicinebymedicineid.getPreventionTypesForMedicineId().add(preventiontype);
		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		related_medicinebymedicineid = medicineDAO.store(related_medicinebymedicineid);
		medicineDAO.flush();

		return preventiontype;
	}

	/**
	 * Load an existing PreventionType entity
	 * 
	 */
	@Transactional
	public Set<PreventionType> loadPreventionTypes() {
		return preventionTypeDAO.findAllPreventionTypes();
	}

	/**
	 * Delete an existing Medicine entity
	 * 
	 */
	@Transactional
	public PreventionType deletePreventionTypeMedicineByReportMedicineId(Integer preventiontype_id, Integer related_medicinebyreportmedicineid_id) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(preventiontype_id, -1, -1);
		Medicine related_medicinebyreportmedicineid = medicineDAO.findMedicineByPrimaryKey(related_medicinebyreportmedicineid_id, -1, -1);

		preventiontype.setMedicineByReportMedicineId(null);
		related_medicinebyreportmedicineid.getPreventionTypesForReportMedicineId().remove(preventiontype);
		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		related_medicinebyreportmedicineid = medicineDAO.store(related_medicinebyreportmedicineid);
		medicineDAO.flush();

		medicineDAO.remove(related_medicinebyreportmedicineid);
		medicineDAO.flush();

		return preventiontype;
	}

	/**
	 */
	@Transactional
	public PreventionType findPreventionTypeByPrimaryKey(Integer id) {
		return preventionTypeDAO.findPreventionTypeByPrimaryKey(id);
	}

	/**
	 * Delete an existing TaskPrevention entity
	 * 
	 */
	@Transactional
	public PreventionType deletePreventionTypeTaskPreventions(Integer preventiontype_id, Integer related_taskpreventions_id) {
		TaskPrevention related_taskpreventions = taskPreventionDAO.findTaskPreventionByPrimaryKey(related_taskpreventions_id, -1, -1);

		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(preventiontype_id, -1, -1);

		related_taskpreventions.setPreventionType(null);
		preventiontype.getTaskPreventions().remove(related_taskpreventions);

		taskPreventionDAO.remove(related_taskpreventions);
		taskPreventionDAO.flush();

		return preventiontype;
	}

	/**
	 * Save an existing PreventionType entity
	 * 
	 */
	@Transactional
	public void savePreventionType(PreventionType preventiontype) {
		PreventionType existingPreventionType = preventionTypeDAO.findPreventionTypeByPrimaryKey(preventiontype.getId());

		if (existingPreventionType != null) {
			if (existingPreventionType != preventiontype) {
				existingPreventionType.setId(preventiontype.getId());
				existingPreventionType.setName(preventiontype.getName());
				existingPreventionType.setReportQuality(preventiontype.getReportQuality());
				existingPreventionType.setQuality(preventiontype.getQuality());
				existingPreventionType.setMemo(preventiontype.getMemo());
			}
			preventiontype = preventionTypeDAO.store(existingPreventionType);
		} else {
			preventiontype = preventionTypeDAO.store(preventiontype);
		}
		preventionTypeDAO.flush();
	}

	/**
	 * Save an existing Medicine entity
	 * 
	 */
	@Transactional
	public PreventionType savePreventionTypeMedicineByReportMedicineId(Integer id, Medicine related_medicinebyreportmedicineid) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(id, -1, -1);
		Medicine existingmedicineByReportMedicineId = medicineDAO.findMedicineByPrimaryKey(related_medicinebyreportmedicineid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingmedicineByReportMedicineId != null) {
			existingmedicineByReportMedicineId.setId(related_medicinebyreportmedicineid.getId());
			existingmedicineByReportMedicineId.setName(related_medicinebyreportmedicineid.getName());
			existingmedicineByReportMedicineId.setNumber(related_medicinebyreportmedicineid.getNumber());
			existingmedicineByReportMedicineId.setCompany(related_medicinebyreportmedicineid.getCompany());
			existingmedicineByReportMedicineId.setQuantityPerCase(related_medicinebyreportmedicineid.getQuantityPerCase());
			existingmedicineByReportMedicineId.setQuantityPerBox(related_medicinebyreportmedicineid.getQuantityPerBox());
			existingmedicineByReportMedicineId.setPhone(related_medicinebyreportmedicineid.getPhone());
			existingmedicineByReportMedicineId.setMemo(related_medicinebyreportmedicineid.getMemo());
			related_medicinebyreportmedicineid = existingmedicineByReportMedicineId;
		} else {
			related_medicinebyreportmedicineid = medicineDAO.store(related_medicinebyreportmedicineid);
			medicineDAO.flush();
		}

		preventiontype.setMedicineByReportMedicineId(related_medicinebyreportmedicineid);
		related_medicinebyreportmedicineid.getPreventionTypesForReportMedicineId().add(preventiontype);
		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		related_medicinebyreportmedicineid = medicineDAO.store(related_medicinebyreportmedicineid);
		medicineDAO.flush();

		return preventiontype;
	}

	/**
	 * Delete an existing Medicine entity
	 * 
	 */
	@Transactional
	public PreventionType deletePreventionTypeMedicineByMedicineId(Integer preventiontype_id, Integer related_medicinebymedicineid_id) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(preventiontype_id, -1, -1);
		Medicine related_medicinebymedicineid = medicineDAO.findMedicineByPrimaryKey(related_medicinebymedicineid_id, -1, -1);

		preventiontype.setMedicineByMedicineId(null);
		related_medicinebymedicineid.getPreventionTypesForMedicineId().remove(preventiontype);
		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		related_medicinebymedicineid = medicineDAO.store(related_medicinebymedicineid);
		medicineDAO.flush();

		medicineDAO.remove(related_medicinebymedicineid);
		medicineDAO.flush();

		return preventiontype;
	}

	/**
	 * Save an existing TaskPrevention entity
	 * 
	 */
	@Transactional
	public PreventionType savePreventionTypeTaskPreventions(Integer id, TaskPrevention related_taskpreventions) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(id, -1, -1);
		TaskPrevention existingtaskPreventions = taskPreventionDAO.findTaskPreventionByPrimaryKey(related_taskpreventions.getId());

		// copy into the existing record to preserve existing relationships
		if (existingtaskPreventions != null) {
			existingtaskPreventions.setId(related_taskpreventions.getId());
			existingtaskPreventions.setMemo(related_taskpreventions.getMemo());
			related_taskpreventions = existingtaskPreventions;
		}

		related_taskpreventions.setPreventionType(preventiontype);
		preventiontype.getTaskPreventions().add(related_taskpreventions);
		related_taskpreventions = taskPreventionDAO.store(related_taskpreventions);
		taskPreventionDAO.flush();

		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		return preventiontype;
	}

	/**
	 * Save an existing Unit entity
	 * 
	 */
	@Transactional
	public PreventionType savePreventionTypeUnitByReportUnitId(Integer id, Unit related_unitbyreportunitid) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(id, -1, -1);
		Unit existingunitByReportUnitId = unitDAO.findUnitByPrimaryKey(related_unitbyreportunitid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingunitByReportUnitId != null) {
			existingunitByReportUnitId.setId(related_unitbyreportunitid.getId());
			existingunitByReportUnitId.setName(related_unitbyreportunitid.getName());
			existingunitByReportUnitId.setMemo(related_unitbyreportunitid.getMemo());
			related_unitbyreportunitid = existingunitByReportUnitId;
		} else {
			related_unitbyreportunitid = unitDAO.store(related_unitbyreportunitid);
			unitDAO.flush();
		}

		preventiontype.setUnitByReportUnitId(related_unitbyreportunitid);
		related_unitbyreportunitid.getPreventionTypesForReportUnitId().add(preventiontype);
		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		related_unitbyreportunitid = unitDAO.store(related_unitbyreportunitid);
		unitDAO.flush();

		return preventiontype;
	}

	/**
	 * Save an existing Unit entity
	 * 
	 */
	@Transactional
	public PreventionType savePreventionTypeUnitByUnitId(Integer id, Unit related_unitbyunitid) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(id, -1, -1);
		Unit existingunitByUnitId = unitDAO.findUnitByPrimaryKey(related_unitbyunitid.getId());

		// copy into the existing record to preserve existing relationships
		if (existingunitByUnitId != null) {
			existingunitByUnitId.setId(related_unitbyunitid.getId());
			existingunitByUnitId.setName(related_unitbyunitid.getName());
			existingunitByUnitId.setMemo(related_unitbyunitid.getMemo());
			related_unitbyunitid = existingunitByUnitId;
		}

		preventiontype.setUnitByUnitId(related_unitbyunitid);
		related_unitbyunitid.getPreventionTypesForUnitId().add(preventiontype);
		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		related_unitbyunitid = unitDAO.store(related_unitbyunitid);
		unitDAO.flush();

		return preventiontype;
	}

	/**
	 * Delete an existing Unit entity
	 * 
	 */
	@Transactional
	public PreventionType deletePreventionTypeUnitByUnitId(Integer preventiontype_id, Integer related_unitbyunitid_id) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(preventiontype_id, -1, -1);
		Unit related_unitbyunitid = unitDAO.findUnitByPrimaryKey(related_unitbyunitid_id, -1, -1);

		preventiontype.setUnitByUnitId(null);
		related_unitbyunitid.getPreventionTypesForUnitId().remove(preventiontype);
		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		related_unitbyunitid = unitDAO.store(related_unitbyunitid);
		unitDAO.flush();

		unitDAO.remove(related_unitbyunitid);
		unitDAO.flush();

		return preventiontype;
	}

	/**
	 * Return all PreventionType entity
	 * 
	 */
	@Transactional
	public List<PreventionType> findAllPreventionTypes(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<PreventionType>(preventionTypeDAO.findAllPreventionTypes(startResult, maxRows));
	}

	/**
	 * Delete an existing Unit entity
	 * 
	 */
	@Transactional
	public PreventionType deletePreventionTypeUnitByReportUnitId(Integer preventiontype_id, Integer related_unitbyreportunitid_id) {
		PreventionType preventiontype = preventionTypeDAO.findPreventionTypeByPrimaryKey(preventiontype_id, -1, -1);
		Unit related_unitbyreportunitid = unitDAO.findUnitByPrimaryKey(related_unitbyreportunitid_id, -1, -1);

		preventiontype.setUnitByReportUnitId(null);
		related_unitbyreportunitid.getPreventionTypesForReportUnitId().remove(preventiontype);
		preventiontype = preventionTypeDAO.store(preventiontype);
		preventionTypeDAO.flush();

		related_unitbyreportunitid = unitDAO.store(related_unitbyreportunitid);
		unitDAO.flush();

		unitDAO.remove(related_unitbyreportunitid);
		unitDAO.flush();

		return preventiontype;
	}
}
